package com.util;

import com.alibaba.fastjson.JSON;
import com.properties.JWTProperties;
import io.jsonwebtoken.*;
import io.jsonwebtoken.security.SignatureException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Date;

@Component
@Slf4j
public class JwtTokenUtils {

    private static final String AUTHORITIES_KEY = "auth";

    @Autowired
    private JWTProperties jwtProperties;

    public String createToken(UserInfo userInfo) {
        long now = System.currentTimeMillis();
        long validityMilliseconds = jwtProperties.getTokenValidityInSeconds() * 1000;
        Date validity = new Date(now + validityMilliseconds);
        return Jwts.builder()
                .setSubject(userInfo.getName())
                .claim(AUTHORITIES_KEY, JSON.toJSONString(userInfo))
                .setExpiration(validity)
                .signWith(SignatureAlgorithm.HS256, jwtProperties.getSecretKey())
                .compact();
    }

    public UserInfo getUserInfo(String token) {
        Claims claims = Jwts.parser()
                .setSigningKey(jwtProperties.getSecretKey())
                .parseClaimsJws(token)
                .getBody();
        return JSON.parseObject((String) claims.get(AUTHORITIES_KEY), UserInfo.class);
    }

    public Boolean validToken(String token) {
        try {
            Jwts.parser().setSigningKey(jwtProperties.getSecretKey()).parseClaimsJws(token);
            return true;
        } catch (SignatureException e) {
            log.info("Invalid JWT signature.");
            log.trace("Invalid JWT signature trace: {}", e);
        } catch (MalformedJwtException e) {
            log.info("Invalid JWT token.");
            log.trace("Invalid JWT token trace: {}", e);
        } catch (ExpiredJwtException e) {
            log.info("Expired JWT token.");
            log.trace("Expired JWT token trace: {}", e);
        } catch (UnsupportedJwtException e) {
            log.info("Unsupported JWT token.");
            log.trace("Unsupported JWT token trace: {}", e);
        } catch (IllegalArgumentException e) {
            log.info("JWT token compact of handler are invalid.");
            log.trace("JWT token compact of handler are invalid trace: {}", e);
        }
        return false;
    }
}
